package bancosys.tec.services.implementor.annotations.visitor;

import jmine.tec.di.annotation.visitor.InjectedAnnotationVisitor;
import jmine.tec.di.cache.TypeMatchLookup;
import jmine.tec.di.metadata.DependencyMetaData;
import jmine.tec.di.resolver.ObjectResolver;
import jmine.tec.di.type.TypeConverter;
import jmine.tec.utils.annotation.visitor.AllMembersAnnotationReader;
import jmine.tec.utils.annotation.visitor.AnnotationVisitorAdapter;
import jmine.tec.utils.annotation.visitor.ClassAnnotationReader;

/**
 * Configura e guarda o {@link ClassAnnotationReader} para {@link DependencyMetaData}
 * 
 * @author takeshi
 */
public class DependencyMetadataParser {

    private final ClassAnnotationReader<DependencyMetaData> dependencyReader = new AllMembersAnnotationReader<DependencyMetaData>();

    /**
     * C'tor
     * 
     * @param staticResolvers os resolvedores estaticos
     * @param typeConvertion o sistema de conversao de tipos
     * @param defaultResolver {@link ObjectResolver}
     */
    public DependencyMetadataParser(TypeMatchLookup<ObjectResolver> staticResolvers, TypeMatchLookup<TypeConverter<?>> typeConvertion,
            ObjectResolver defaultResolver) {
        super();
        addAnnotationVisitor(new InjectedAnnotationVisitor(staticResolvers, defaultResolver));
        addAnnotationVisitor(new InputAnnotationVisitor(typeConvertion, staticResolvers));
        addAnnotationVisitor(new ParameterAnnotationVisitor(typeConvertion, staticResolvers));
        addAnnotationVisitor(new WithPreffixAnnotationVisitor(typeConvertion));
        addAnnotationVisitor(new WithRegexAnnotationVisitor(typeConvertion));
        addAnnotationVisitor(new AllPropertiesAnnotationVisitor());
        addAnnotationVisitor(new SuffixOfAnnotationVisitor(typeConvertion));
    }

    /**
     * Adiciona annotation visitors
     * 
     * @param visitor {@link AnnotationVisitorAdapter}
     */
    private void addAnnotationVisitor(AnnotationVisitorAdapter<? extends DependencyMetaData> visitor) {
        dependencyReader.addMethodAnnotationVisitor(visitor);
        dependencyReader.addParameterAnnotationVisitor(visitor);
        dependencyReader.addFieldAnnotationVisitor(visitor);
    }

    /**
     * @return {@link ClassAnnotationReader} de {@link DependencyMetaData}
     */
    public ClassAnnotationReader<DependencyMetaData> getClassReader() {
        return dependencyReader;
    }

}
